有负数数组,意味着presum[]无序,先想到presum解法,可配合其他条件

有负数数组、和>=T的最短子段

用了presum[]单调栈

int shortestSubarray(vector<int>& A, int T) {
	// 求presum[i]-presum[j]>=T的最短子段长
	// 对于左端点presum[j],如果在presum[]中能找到下一个更小(或相等)的数presum[k],
	// 因为presum[i]-presum[k]更大(或相等)、且子段i-k更短,所以presum[k]占优。
	// 只需考虑占优选项,用单调栈
	// 配合两指针法
	const int N = A.size();
	vector<long> presum(N + 1, 0);
	for (int i = 1; i <= N; i++) {
		presum[i] = presum[i - 1] + A[i - 1];
	}

	int ans = INT_MAX;
	deque<int> dq;
	for (int k = 0; k <= N; k++) {
		while (!dq.empty() && presum[k] <= presum[dq.back()]) {  // 只考虑占优策略
			dq.pop_back();
		}
		dq.push_back(k);

		while (!dq.empty() && presum[k] - presum[dq[0]] >= T) {
			ans = min(ans, k - dq[0]);
			dq.pop_front();  // dp[0]对后面的k都不会取得更短子段
		}
	}
	return ans != INT_MAX ? ans : -1;
}

用runningSum解法,至少O(NlgN),超时

// Time Limit Exceeded
int shortestSubarray(vector<int>& A, int K) {
    map<int, int> mp; // sum=>lastIdx
    int runningSum = 0;
    mp[runningSum] = -1;

    int ans = INT_MAX;
    for (int i = 0; i < A.size(); i++) {
        runningSum += A[i];
        // 在旧runningSum集合mp中找toFind,
        // 使runningSum-toFind>=K,toFind<=runningSum-K
        int x = runningSum - K;
        auto ub = mp.upper_bound(x);
        for (auto it = mp.begin(); it != ub; it++) {
            ans = min(ans, i - it->second);
        }
        mp[runningSum] = i;
    }
    return ans != INT_MAX ? ans : -1;
}